/**
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2007，所有权利保留。
 * 
 * 项目名：	rumba
 * 文件名：	CompareOperator.java
 * 模块说明：	
 * 修改历史：
 * Dec 14, 2007 - lxm - 创建。
 */
package com.hd123.rumba.gwt.cpnts.filter.client;

import com.hd123.rumba.gwt.base.client.exception.ClientBizException;

/**
 * 比较运算符
 * 
 * @author lxm
 * 
 */
final class CompareOperator {

  public static final CompareOperator Equal = new CompareOperator(0, "等于 =", new Simple_ExpGen("="));
  public static final CompareOperator NotEqual = new CompareOperator(1, "不等于 <>",
      new Simple_ExpGen("<>"));
  public static final CompareOperator Greater = new CompareOperator(2, "大于 >", new Simple_ExpGen(
      ">"));
  public static final CompareOperator Less = new CompareOperator(3, "小于 <", new Simple_ExpGen("<"));
  public static final CompareOperator GreaterAndEqual = new CompareOperator(4, "大于等于 >=",
      new Simple_ExpGen(">="));
  public static final CompareOperator LessAndEqual = new CompareOperator(5, "小于等于 <=",
      new Simple_ExpGen("<="));
  public static final CompareOperator Like = new CompareOperator(6, "类似于", new Like_ExpGen(false));
  public static final CompareOperator NotLike = new CompareOperator(7, "不类似于",
      new Like_ExpGen(true));
  public static final CompareOperator In = new CompareOperator(8, "在...之中", new In_ExpGen(false));
  public static final CompareOperator NotIn = new CompareOperator(9, "不在...之中", new In_ExpGen(true));
  public static final CompareOperator IsNull = new CompareOperator(10, "为空", new Null_ExpGen(false));
  public static final CompareOperator NotNull = new CompareOperator(11, "不为空",
      new Null_ExpGen(true));
  public static final CompareOperator[] All = new CompareOperator[] {
      Equal, NotEqual, Greater, Less, GreaterAndEqual, LessAndEqual, Like, NotLike, In, NotIn,
      IsNull, NotNull };

  private CompareOperator(int value, String caption, ExpGenerator expGen) {
    super();
    this.value = value;
    this.caption = caption;
    this.expGen = expGen;
  }

  public boolean equals(Object obj) {
    if (obj == null)
      return false;
    if (!(obj instanceof CompareOperator))
      return false;
    return this.value == ((CompareOperator) obj).getValue();
  }

  public int hashCode() {
    return this.value * 11 + 51;
  }

  private int value;
  private String caption;
  private ExpGenerator expGen;

  public String getCaption() {
    return caption;
  }

  public int getValue() {
    return value;
  }

  public String getRunnableExp(String leftExp, String rightExp) throws ClientBizException {
    if (this.expGen == null)
      return null;
    return this.expGen.getRunnableExp(leftExp, rightExp);
  }

  private static abstract class ExpGenerator {
    public abstract String getRunnableExp(String leftExp, String rightExp) throws ClientBizException;
  }

  private static class Simple_ExpGen extends ExpGenerator {
    private String operator;

    public Simple_ExpGen(String operator) {
      super();
      this.operator = operator;
    }

    public String getRunnableExp(String leftExp, String rightExp) throws ClientBizException {
      StringBuffer sb = new StringBuffer();
      sb.append(leftExp);
      sb.append(" " + this.operator + " ");
      sb.append(rightExp);
      return sb.toString();
    }
  }

  private static class Like_ExpGen extends ExpGenerator {
    private boolean withNot;

    public Like_ExpGen(boolean withNot) {
      super();
      this.withNot = withNot;
    }

    public String getRunnableExp(String leftExp, String rightExp) throws ClientBizException {
      StringBuffer sb = new StringBuffer();
      if (withNot)
        sb.append(" not (");
      sb.append(leftExp);
      sb.append(" like ");

      String re = rightExp.trim();
      // 只有当字符串以“"”或“'”开头，且不以“"%”或“'%”开头，将其开头替换为“'%”
      if (re.matches("^['\"][^%]"))
        re.replaceAll("^['\"]", "'%");
      // 只有当字符串以“"”或“'”结尾，且不以“%"”或“%'”结尾，将其结尾替换为“'%”
      if (re.matches("[^%]['\"]$"))
        re.replaceAll("['\"]$", "%'");
      sb.append(re);

      if (withNot)
        sb.append(")");
      return sb.toString();
    }
  }

  private static class In_ExpGen extends ExpGenerator {
    private boolean withNot;

    public In_ExpGen(boolean withNot) {
      super();
      this.withNot = withNot;
    }

    public String getRunnableExp(String leftExp, String rightExp) throws ClientBizException {
      StringBuffer sb = new StringBuffer();
      sb.append(leftExp);
      if (withNot)
        sb.append(" not in (");
      else
        sb.append(" in (");

      String re = rightExp.trim();
      // 判断是否以引号开头。
      boolean quot = re.matches("^['\"]");
      // 去掉开头和结尾的引号。
      if (quot) {
        re.replaceAll("^['\"]", "");
        re.replaceAll("['\"]$", "");
      }
      String[] reItems = re.split(",");
      boolean first = true;
      for (int i = 0; i < reItems.length; i++) {
        String reItem = reItems[i];
        if (!first)
          sb.append(", ");
        if (quot)
          sb.append("'");
        reItem = reItem.trim();
        reItem.replaceAll("'", "''");
        reItem.replaceAll("\"", "\"\"");
        sb.append(reItem);
        if (quot)
          sb.append("'");
        first = false;
      }

      sb.append(")");
      return sb.toString();
    }
  }

  private static class Null_ExpGen extends ExpGenerator {
    private boolean withNot;

    public Null_ExpGen(boolean withNot) {
      super();
      this.withNot = withNot;
    }

    public String getRunnableExp(String leftExp, String rightExp) throws ClientBizException {
      StringBuffer sb = new StringBuffer();
      sb.append(leftExp);
      if (withNot)
        sb.append(" is not null");
      else
        sb.append(" is null");
      return sb.toString();
    }
  }

}
